home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
SGI Developer Toolbox 6.1
/
SGI Developer Toolbox 6.1 - Disc 4.iso
/
public
/
bit
/
src
/
forms
/
FORMS
/
counter.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-08-01
|
7KB
|
230 lines
/*
* counter.c
*
* Forms Object class: COUNTER
*
* Written by: Mark Overmars
*
* Version 2.1 a
* Date: Sep 29, 1992
*/
#include <malloc.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "forms.h"
/* The special information for counters. */
typedef struct {
float value; /* Value of the slider */
float min,max; /* Bounds */
float sstep,lstep; /* Step sizes */
int prec; /* precision when displaying value */
int always; /* whether always returning value */
int mouseobj; /* Button under the mouse */
} SPEC;
static int timdel; /* Delay since last value change */
static void draw_counter(FL_OBJECT *ob)
/* Draws a counter */
{
float xx[5], ww[5];
char str[64];
int i, btype[5];
SPEC *sp = (SPEC *) ob->spec;
/* Compute boxtypes */
for (i=0; i<5; i++)
if (sp->mouseobj == i && ob->boxtype == FL_UP_BOX)
btype[i] = FL_DOWN_BOX;
else
btype[i] = ob->boxtype;
if (btype[4] == FL_UP_BOX) btype[4] = FL_DOWN_BOX;
/* Compute sizes */
if (ob->type == FL_NORMAL_COUNTER)
{
xx[0] = ob->x + 0.00 * ob->w; ww[0] = 0.15 * ob->w;
xx[1] = ob->x + 0.15 * ob->w; ww[1] = 0.15 * ob->w;
xx[2] = ob->x + 0.70 * ob->w; ww[2] = 0.15 * ob->w;
xx[3] = ob->x + 0.85 * ob->w; ww[3] = 0.15 * ob->w;
xx[4] = ob->x + 0.30 * ob->w; ww[4] = 0.40 * ob->w;
}
else
{
xx[1] = ob->x + 0.00 * ob->w; ww[1] = 0.20 * ob->w;
xx[2] = ob->x + 0.80 * ob->w; ww[2] = 0.20 * ob->w;
xx[4] = ob->x + 0.20 * ob->w; ww[4] = 0.60 * ob->w;
}
/* Create value string */
/* Draw the thing */
sprintf(str,"%.*f",sp->prec,sp->value);
if (ob->type == FL_NORMAL_COUNTER)
{
fl_drw_box(btype[0],xx[0],ob->y,ww[0],ob->h,ob->col1,FL_COUNTER_BW);
fl_drw_text(FL_ALIGN_CENTER,xx[0],ob->y,ww[0],ob->h,ob->col2,0.0,0,"@<<");
}
fl_drw_box(btype[1],xx[1],ob->y,ww[1],ob->h,ob->col1,FL_COUNTER_BW);
fl_drw_text(FL_ALIGN_CENTER,xx[1],ob->y,ww[1],ob->h,ob->col2,0.0,0,"@<");
fl_drw_box(btype[4],xx[4],ob->y,ww[4],ob->h,ob->col1,FL_COUNTER_BW);
fl_drw_text(FL_ALIGN_CENTER,xx[4],ob->y,ww[4],ob->h,
ob->lcol,ob->lsize,ob->lstyle,str);
fl_drw_box(btype[2],xx[2],ob->y,ww[2],ob->h,ob->col1,FL_COUNTER_BW);
fl_drw_text(FL_ALIGN_CENTER,xx[2],ob->y,ww[2],ob->h,ob->col2,0.0,0,"@>");
if (ob->type == FL_NORMAL_COUNTER)
{
fl_drw_box(btype[3],xx[3],ob->y,ww[3],ob->h,ob->col1,FL_COUNTER_BW);
fl_drw_text(FL_ALIGN_CENTER,xx[3],ob->y,ww[3],ob->h,ob->col2,0.0,0,"@>>");
}
fl_drw_text_beside(ob->align,ob->x,ob->y,ob->w,ob->h,
ob->lcol,ob->lsize,ob->lstyle,ob->label);
}
static void calc_mouse_obj(FL_OBJECT * ob, float mx, float my)
{
SPEC *sp = (SPEC *) ob->spec;
sp->mouseobj = -1;
if (my<ob->y || my>ob->y + ob->h) return;
if (ob->type == FL_NORMAL_COUNTER)
{
if (mx < ob->x + 0.15 * ob->w) sp->mouseobj = 0;
else if (mx < ob->x + 0.30 * ob->w) sp->mouseobj = 1;
else if (mx < ob->x + 0.70 * ob->w) sp->mouseobj = 4;
else if (mx < ob->x + 0.85 * ob->w) sp->mouseobj = 2;
else if (mx < ob->x + 1.00 * ob->w) sp->mouseobj = 3;
}
else
{
if (mx < ob->x + 0.20 * ob->w) sp->mouseobj = 1;
else if (mx < ob->x + 0.80 * ob->w) sp->mouseobj = 4;
else if (mx < ob->x + 1.00 * ob->w) sp->mouseobj = 2;
}
}
static int handle_mouse(FL_OBJECT *ob, int event, float mx, float my)
/* handles an event on ob*/
{
SPEC *sp = (SPEC *) ob->spec;
int changeval = 0;
if (event == FL_RELEASE)
{ sp->mouseobj = -1; fl_redraw_object(ob); return 0;}
else if (event == FL_PUSH)
{ calc_mouse_obj(ob,mx,my); if (sp->mouseobj != -1) changeval = 1; timdel = 1;}
else if (event == FL_MOUSE && sp->mouseobj != -1)
changeval = (timdel++ % 12 == 0);
if (changeval)
{
if (sp->mouseobj == 0) sp->value -= sp->lstep;
if (sp->mouseobj == 1) sp->value -= sp->sstep;
if (sp->mouseobj == 2) sp->value += sp->sstep;
if (sp->mouseobj == 3) sp->value += sp->lstep;
if (sp->value < sp->min) sp->value = sp->min;
if (sp->value > sp->max) sp->value = sp->max;
fl_redraw_object(ob);
}
return changeval;
}
static int valchanged; /* whether value has changed since last time */
static int handle_counter(FL_OBJECT *ob,int event,float mx,float my,char key)
/* Handles an event */
{
SPEC *sp = (SPEC *) ob->spec;
float val;
switch (event)
{
case FL_DRAW:
draw_counter(ob);
return 0;
case FL_PUSH:
valchanged = 0;
if (handle_mouse(ob,event,mx,my))
{ if (sp->always) return 1; else { valchanged = 1; return 0;} }
break;
case FL_MOUSE:
if (handle_mouse(ob,event,mx,my))
{ if (sp->always) return 1; else { valchanged = 1; return 0;} }
break;
case FL_RELEASE:
return (handle_mouse(ob,event,mx,my) || (! sp->always && valchanged));
case FL_FREEMEM:
free(ob->spec);
return 0;
}
return 0;
}
/*------------------------------*/
FL_OBJECT *fl_create_counter(int type,float x,float y,float w,float h,char label[])
/* creates an object */
{
FL_OBJECT *ob;
SPEC *sp;
ob = fl_make_object(FL_COUNTER,type,x,y,w,h,label,handle_counter);
ob->boxtype = FL_COUNTER_BOXTYPE;
ob->col1 = FL_COUNTER_COL1;
ob->col2 = FL_COUNTER_COL2;
ob->align = FL_COUNTER_ALIGN;
ob->lcol = FL_COUNTER_LCOL;
ob->spec = (int *) fl_malloc(sizeof(SPEC));
sp = ((SPEC *)(ob->spec));
sp->min = -1000000.0;
sp->max = 1000000.0;
sp->sstep = 0.1;
sp->lstep = 1.0;
sp->value = 0.0;
sp->prec = 1;
sp->always = FALSE;
sp->mouseobj = -1;
return ob;
}
FL_OBJECT *fl_add_counter(int type, float x, float y, float w, float h, char label[])
/* Adds an object */
{
FL_OBJECT *ob;
ob = fl_create_counter(type,x,y,w,h,label);
fl_add_object(fl_current_form,ob);
return ob;
}
void fl_set_counter_value(FL_OBJECT *ob, float val)
{
((SPEC *)(ob->spec))->value = val;
fl_redraw_object(ob);
}
void fl_set_counter_bounds(FL_OBJECT *ob, float min, float max)
{
((SPEC *)(ob->spec))->min = min;
((SPEC *)(ob->spec))->max = max;
fl_redraw_object(ob);
}
void fl_set_counter_step(FL_OBJECT *ob, float small, float large)
{
((SPEC *)(ob->spec))->sstep = small;
((SPEC *)(ob->spec))->lstep = large;
fl_redraw_object(ob);
}
void fl_set_counter_precision(FL_OBJECT *ob,int prec)
{
((SPEC *)(ob->spec))->prec = prec;
fl_redraw_object(ob);
}
float fl_get_counter_value(FL_OBJECT *ob)
{ return ((SPEC *)(ob->spec))->value; }
void fl_set_counter_return(FL_OBJECT *ob, int value)
/* Sets whether to return value all the time */
{
((SPEC *)(ob->spec))->always = value;
}